package com.lenovo.leos.filebrowser.engine.operation;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.xmlpull.v1.XmlPullParserException;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnDismissListener;
import android.content.Intent;
import android.content.res.XmlResourceParser;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.PowerManager;
import android.os.StatFs;
import android.util.Log;
import android.view.KeyEvent;
import android.widget.Toast;

import com.lenovo.leos.filebrowser.R;
import com.lenovo.leos.filebrowser.engine.util.FileClipBoard;
import com.lenovo.leos.filebrowser.engine.util.FileUtil;
import com.lenovo.leos.filebrowser.engine.util.MimeTypeParser;
import com.lenovo.leos.filebrowser.engine.util.MimeTypes;

/*
 * This class takes charge of file operations,such as copy,paste,cut,rename,new,delete,and attributes display.
 * It is started by FileBrowser with startActivityForResult() method.
*/

public class FileMan extends Activity{
	private static final String TAG = "FileMan";
	Bundle bundle;
	Intent intent;

	private HashMap<String,String> attriMap = new HashMap<String, String>();
	private int requestCode = -1;
	private ProgressDialog mProgressDialog;
	private static final int MAX_PROGRESS = 100;
	private DeleteThread mDeleteThread = null;
	private CopyOrCutThread mCopyCutThread = null;
	
	private FileClipBoard mfcpSelected = FileClipBoard.getInstance();
	
	private ArrayList<String> mlNewFiles = new ArrayList<String>();
	
	MyEventHandler mEH = null;
	
	private static final int COPY_ONSAME_MSG = 1000; 
	private static final int COPY_NOSPACE_MSG = 2000;
	private static final int COPY_ONSAMEDIR_MSG = 3000;
	private static final int COPY_ONSAMEDIR_MSG_ONLY_ONE = 3001;
	private static final int COPY_BUFFER_MAXSIZE = 0x40000;
	private static final int DEST_INVALID = 1000001;
	private static final int SRC_INVALID = 1000002;
	
	
	private boolean mNeedBroadCastFileChanged = false;
	private static MimeTypes mMimeTypes = null;
	private int flag = 0;
	boolean mCutType;

	@Override
	public void onCreate(Bundle icicle){
		Log.i(TAG, "==> onCreate");
		
		super.onCreate(icicle);
		mProgressDialog = new ProgressDialog(FileMan.this);
		mProgressDialog.setOnDismissListener(new OnDismissListener(){
			public void onDismiss(DialogInterface arg0) {
				// TODO Auto-generated method stub
				if(mCopyCutThread != null)
					mCopyCutThread.toStop();
				if(mDeleteThread != null)
					mDeleteThread.toStop();				
			//	finish();
			}			
		});
		/* get Bundle from Intent */
	   intent = FileMan.this.getIntent();
	   bundle = intent.getExtras();
	   mEH = new MyEventHandler(Looper.myLooper());
	   doAction();
	}
	
/*	@Override
	public void onDestroy(){
		if(mProgressDialog != null){
			mProgressDialog.dismiss();
			mProgressDialog = null;	
		}
		super.onDestroy();
	}*/
	
	private class WorkThread extends Thread{
		 boolean mStop = false;
		 boolean mResume = true;
		 protected PowerManager.WakeLock mWakeLock;
		 Context mContext;
		 
		 public WorkThread(Context context) {
			  mContext = context;
	        threadInt();
	     }
		 
		 private void threadInt(){
			 PowerManager powerManager = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
	       mWakeLock = powerManager.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, TAG);
		 }
		 
		 @Override
		 public void finalize() {
			 Log.d(TAG, "******* Thread finalize ***********");
	        if (mWakeLock != null && mWakeLock.isHeld()) {
	            mWakeLock.release();
	           }
	     }
		 
		 public void toStop(){
			 mResume = true;
			 mStop = true;
		 }	 
		 public boolean isStop(){
			 return mStop;
		 }
	}
	
	private class DeleteThread extends WorkThread{
		 
		public DeleteThread(Context context) {
			super(context);
			// TODO Auto-generated constructor stub
		}

		protected void delete(File file){
			Log.i(TAG, " == > delete  mStopDelete = "+mStop);
			
			if (file.isDirectory()){ 
				File[] childs = file.listFiles(); 
				//if the directory is empty, delete it directly.
				if(childs.length > 0){
					//if the directory is not empty,empty it before delete.
					int i;
					for (i=0; i<childs.length; i++) {
						if(mStop || !childs[i].exists())
							break;
		       	 		delete(childs[i]);
		       	 		if(mNeedBroadCastFileChanged == false){
		       	 			mNeedBroadCastFileChanged = neadBroadCast(childs[i].toString());
		       	 		}
		       	 	}
				}
			}else{
				if(mNeedBroadCastFileChanged == false){
					mNeedBroadCastFileChanged = neadBroadCast(file.getName());
	      	    }
	        }
			
			//delete file or directory which is empty
			if(!mStop || file.exists())
			   file.delete();		    	   
			if(mProgressDialog != null && !file.isDirectory())
	       	      mProgressDialog.incrementProgressBy(1);
		}
	}
	
	public class CopyOrCutThread extends WorkThread{
		
		public CopyOrCutThread(Context context) {
			super(context);
			// TODO Auto-generated constructor stub
		}

		List<File> mSrcFileList;
		File mDestDir;
		
		boolean mReplace = true;
		boolean mReplaceDir = true;
		
		boolean mbSkipAll = false;
		boolean mbSkip = false;
		boolean mbCancel = false;
		boolean mbOnlyOneSrc = false;
				
		public void toResume(){
			mResume = true;
		}
		//add 2010-12-28 by xieqm
		public boolean onSameFileExist(String sFileName){
			mResume = false;
			mStop = false;
			
			Message msg = mEH.obtainMessage(COPY_ONSAME_MSG, 0, 0, sFileName);
			mEH.sendMessage(msg);
			
			while(mResume == false && mStop == false){
				try {
					join(100);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			
			boolean bReplace = mReplace;
			mReplace = true;
			return bReplace;
		}
		//end
		
		public void onNoEnoughSpace(){
			mResume = false;
			mStop = false;
			//mProgressDialog.dismiss();
			Message msg = mEH.obtainMessage(COPY_NOSPACE_MSG, 0, 0, "");
			mEH.sendMessage(msg);
			
			while(mResume == false && mStop == false){
				try {
					join(100);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		
		public boolean onSameDirExist(String sDirName){
			mResume = false;
			mStop = false;
			
			Message msg = null;
			
			if (!mbOnlyOneSrc){
				msg = mEH.obtainMessage(COPY_ONSAMEDIR_MSG, 0, 0, sDirName);
			}else {
				msg = mEH.obtainMessage(COPY_ONSAMEDIR_MSG_ONLY_ONE, 0, 0, sDirName);
				mbOnlyOneSrc = false;
			}
			mEH.sendMessage(msg);
			
			while(mResume == false && mStop == false){
				try {					
					join(100);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			
			boolean bReplace = mReplaceDir;
			mReplaceDir = true;
//			Log.d(TAG, "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% bReplace=" + bReplace);
			return bReplace;
		}
		
		//copy files from one directory to another
		private boolean copy(File source, File dest) throws Exception {
			/* avoid copy a derectory to it's child derectory -by tankangxi */
			File newdest = null;
			
			if (source.isFile()) {

				// check the left space
				StatFs sf;
				String sSDRoot = FileUtil.sdroot.substring(0, FileUtil.sdroot.length() - 1);
				if (dest.getAbsolutePath().toLowerCase().startsWith(sSDRoot)) {
					sf = new StatFs(FileUtil.sdroot);
					if (((long) sf.getAvailableBlocks() * sf.getBlockSize()) > ((long) (source
							.length() + 1024))) {

					} else {
						if (mCopyCutThread != null && !mStop) {
							mCopyCutThread.onNoEnoughSpace();
						}
						return false;
					}
				} else if (dest.getAbsolutePath().toLowerCase().startsWith(
						FileUtil.sdroot)) {
					sf = new StatFs(FileUtil.sdroot);
				}
			}
			
			/* avoid copy a derectory to it's child derectory -by tankangxi */
			if (source.getName().equals(dest.getName()) == true
					&& dest.getAbsolutePath()
							.contains(source.getAbsolutePath()) == true
					&& dest.getAbsolutePath().length() > source
							.getAbsolutePath().length()) {
				return false;
			}

			if (source.isDirectory()) {
				newdest = new File(dest.getAbsolutePath() + "/" + source.getName());
				
				if (!newdest.exists()) {
					newdest.mkdir();
					
					// add the new dir in new file list
					if (newdest.getParentFile().equals(mDestDir)){
						mlNewFiles.add(newdest.getAbsolutePath());
						Log.i(TAG, "the new dir is " + newdest.getAbsolutePath());
					}
					
				} else if (newdest.exists() && mCopyCutThread != null) {
					if(newdest.equals(source)){
						Log.i(TAG, "copy dir in its parent dir");
						
						// new folder name 
						String newName = null;
						File tempDest = null;
						newName = newdest.getAbsolutePath() + "(" + getResources().getString(R.string.copy)  + ")";

						tempDest = new File(newName);
						int nIndex = 1; 
						while(tempDest.exists()){
							newName = newdest.getAbsolutePath() + "(" + 
								getResources().getString(R.string.copy) + String.valueOf(nIndex) + ")";
							tempDest = new File(newName);
							nIndex += 1;
						}
						
						// make dir
						newdest = tempDest;
						newdest.mkdir();
						
						// add the new dir in new file list
						if (newdest.getParentFile().equals(mDestDir)){
							mlNewFiles.add(newdest.getAbsolutePath());
							Log.i(TAG, "the new dir is " + newdest.getAbsolutePath());
						}
						
					}else {
						if (!mCopyCutThread.onSameDirExist(newdest.getName())) {
							Log.i(TAG, "return false for onSameDirExist");
							return false;
						}						
					}									
				}

				String[] children = source.list();
				for (int i = 0; i < children.length; i++) {
					if (mStop)
						break;
					File sf = new File(source, children[i]);
					copy(sf, newdest);
				}
			} else {
				if(mStop)
					return false;
				
				String sDestFileName = dest.getAbsolutePath() + "/" + source.getName();
				if(source.getAbsolutePath().equals(sDestFileName)){
					String sFileNameWithoutExt = FileUtil.getFileNameWithoutExt(source.getName());
				//	Log.d(TAG, "******111 file name :" + sFileNameWithoutExt);
					String sFileExt = FileUtil.getExtension(source.getName());
					if(sFileExt.length() > 0){
						sDestFileName = dest.getAbsolutePath() + "/" + sFileNameWithoutExt + "(" + getResources().getString(R.string.copy)  + ")" + sFileExt;
					}else{
						sDestFileName = dest.getAbsolutePath() + "/" + sFileNameWithoutExt +"(" + getResources().getString(R.string.copy) + ")";
					}
					newdest = new File(sDestFileName);
					int nIndex = 1; 
					while(newdest.exists()){
						if(sFileExt.length() > 0){
							sDestFileName = dest.getAbsolutePath() + "/" + sFileNameWithoutExt + "(" + getResources().getString(R.string.copy) +  nIndex   + ")" + sFileExt;
						}else{
							sDestFileName = dest.getAbsolutePath() + "/" + sFileNameWithoutExt +"("+ getResources().getString(R.string.copy) + nIndex +")";
						}
					   newdest = new File(sDestFileName);
					   nIndex += 1;
					}
				}else{				
				   newdest = new File(sDestFileName);
					if (newdest.exists() && mCopyCutThread != null) {
						if (mCopyCutThread.onSameFileExist(newdest.getName()) == false) {
							 Log.i(TAG, "after onSameFileExist false");
							return false;
						} else {
							Log.i(TAG, "after onSameFileExist true");
							if (mStop) {
								Log.i(TAG, "after onSameFileExist return false");
								return false;
							}
						}
					}
				}
				
				if(mNeedBroadCastFileChanged == false)
					mNeedBroadCastFileChanged = neadBroadCast(sDestFileName);
				
				try {
					// Create channel on the source
					FileChannel srcChannel = new FileInputStream(source).getChannel();
					// Create channel on the destination
					FileChannel dstChannel = new FileOutputStream(newdest).getChannel();
					// Copy file contents from source to destination
					int nOffset = 0;
					
					while(nOffset < srcChannel.size() && !mStop){
						if(nOffset + COPY_BUFFER_MAXSIZE < srcChannel.size()){
					      dstChannel.transferFrom(srcChannel, nOffset, COPY_BUFFER_MAXSIZE);
					      nOffset += COPY_BUFFER_MAXSIZE;
						}else{
							dstChannel.transferFrom(srcChannel, nOffset, srcChannel.size()-nOffset);
							break;
						}
					}					
					// Close the channels
					srcChannel.close();
					dstChannel.close();
					
					if(mStop){
					//    Log.d("wuqf", "********* is Stopped by mannual *******");
					    newdest.delete();
					    return false;
					}	
					
					if(mCutType){
						source.delete();
					}
					
					// add the new file in new file list
					if (newdest.getParentFile().equals(mDestDir)){
						mlNewFiles.add(newdest.getAbsolutePath());
						Log.i(TAG, "the new file is " + newdest.getAbsolutePath());
					}
					mProgressDialog.incrementProgressBy(1);
				} catch (IOException e) {
					e.printStackTrace();
				}
			}			
			return true;
		}
		
/*		private void cut(File source, File dest) throws Exception{
			File newdest = null;

		//	Log.d(TAG, "******* to cut : " + source.getAbsolutePath());
			if(source.isFile()){				
				//check the left space
				StatFs sf;
				String sSDRoot = FileUtil.sdroot.substring(0, FileUtil.sdroot.length()-1);
				if (dest.getAbsolutePath().toLowerCase().startsWith(sSDRoot)) {
					sf = new StatFs(FileUtil.sdroot);
					if (((long) sf.getAvailableBlocks() * sf.getBlockSize()) > ((long) (source.length() + 1024))) {
					} else {
						if (mCopyCutThread != null && mCopyCutThread.mStop == false) {
							mCopyCutThread.onNoEnoughSpace();
						}
					}
				} else if (dest.getAbsolutePath().toLowerCase().startsWith(
						FileUtil.sdroot)) {
					sf = new StatFs(FileUtil.sdroot);
				}
			}
			
			if (source.getName().equals(dest.getName()) == true
					&& dest.getAbsolutePath().contains(source.getAbsolutePath()) == true
					&& dest.getAbsolutePath().length() > source.getAbsolutePath().length()) {
				return;
			}
			
			if (source.isDirectory()) {
				newdest = new File(dest.getAbsolutePath() + "/" + source.getName());			
				if (!newdest.exists()) {
					String[] children = source.list();
					for (int i = 0; i < children.length; i++) {
						if(mStop || !source.exists() || !dest.exists())
							break;
						File sf = new File(source, children[i]);
						cut(sf, newdest);
					}
					//source.renameTo(newdest);
					myRenameto(source, dest);
					mProgressDialog.incrementProgressBy(1);
					
				}else if(newdest.exists() && mCopyCutThread != null){
					 
						if(!mCopyCutThread.onSameDirExist(newdest.getName())){
							return;
						}
						String[] children = source.list();
						for (int i = 0; i < children.length; i++) {
							if(mStop || !source.exists() || !dest.exists())
								break;
							File sf = new File(source, children[i]);
							cut(sf, newdest);
						}
						source.delete();
				}
				
			}else{
				if (mStop || !source.exists() || !dest.exists())
					return;

				String sDestFileName = dest.getAbsolutePath() + "/" + source.getName();
				newdest = new File(sDestFileName);
				if (newdest.exists() && mCopyCutThread != null) {
					if (mCopyCutThread.onSameFileExist(newdest.getName()) == false)
						return;
				}

				if (mNeedBroadCastFileChanged == false)
					mNeedBroadCastFileChanged = neadBroadCast(sDestFileName);

				myRenameto(source, dest);
				mProgressDialog.incrementProgressBy(1);
			}			
							
		}
*/		
		protected void delete(File file){
				 Log.i(TAG, "==> delete ");
					
					if (file.isDirectory()){ 
						String[] child = file.list();
						//if the directory is empty, delete it directly.
						if(child.length > 0){
							//if the directory is not empty,empty it before delete.
							int i;
							for (i=0; i<child.length; i++) {
								if(mStop || !file.exists())
									break;
				       	 	delete(new File(file, child[i]));
				       	 	if(mNeedBroadCastFileChanged == false){
				       	 	   mNeedBroadCastFileChanged = neadBroadCast(child[i]);
				       	 		}
				       	 	}
						}
			      }else{
			    	   if(mNeedBroadCastFileChanged == false){
			      	 	mNeedBroadCastFileChanged = neadBroadCast(file.getName());
			      	    }
			        }
					if(!mStop || file.exists())
					   file.delete();	
				}
		
	   public void run(){
		   mWakeLock.acquire();
		   
//		   int nTotalFileCount = getFileCount(mSrcFileList);
//         Log.d(TAG, " mDestDir="+mDestDir);
		   
		   Log.i(TAG, "run copy/cut thread");
		   
		   if(!mDestDir.exists()){
			   Log.e(TAG, "the dest is nonexistent");
			   Message msg = mEH.obtainMessage(DEST_INVALID, 0, 0, mDestDir.getName());
				mEH.sendMessage(msg);
				wrong2browser();
		   }else {
//				Log.i(TAG, "the file amount is " + String.valueOf(mSrcFileList.size()));

				// do this copy in order to update FileClipBoard 
				List<File> src = mSrcFileList;
				if (src.size() == 1){
					mbOnlyOneSrc = true;
				}
				
				// clear the new file list
				mlNewFiles.clear();

				for (int i = 0; i < src.size() && !mStop; i++) {
					File source = src.get(i);

//					Log.i(TAG, "the file is " + source.getAbsolutePath());

					// source invalid
					if (!source.exists()) {
						Log.e(TAG, "source file is invalid : " + source.getAbsolutePath());

						if (!mbSkipAll) {
							String name = source.getName();
							Log.e(TAG, "send message to main thread");
							Message msg = mEH.obtainMessage(SRC_INVALID, 0, 0,
									name);
							mEH.sendMessage(msg);

							mResume = false;
							while (mResume == false) {
								try {
									join(100);
								} catch (InterruptedException e1) {
									// TODO Auto-generated catch block
									e1.printStackTrace();
								}
							}
						}

//						Log.i(TAG, "mbcancel is" + String.valueOf(mbCancel));
//						Log.i(TAG, "mbSkip is" + String.valueOf(mbSkip));
//						Log.i(TAG, "mbSkipAll is" + String.valueOf(mbSkipAll));

						if (mbCancel) {
							Log.i(TAG, "user cancel");
							mfcpSelected.removeFile(source);
							mbCancel = false;// [check]
							break;
						} else if (mbSkip) {
							Log.i(TAG, "user skip one");
							mfcpSelected.removeFile(source);
//							Log.i(TAG, "the file number is clip is "
//									+ mfcpSelected.getSize());
//							Log.i(TAG, "i = " + String.valueOf(i));
//							Log.i(TAG, "mStop is " + String.valueOf(mStop));

							mbSkip = false;
							continue;
						} else if (mbSkipAll) {
//							Log.i(TAG, "user skip all");
							mfcpSelected.removeFile(source);
							continue;
						}
						// break;
					} else {
						Log.i(TAG, "the file is valid"
								+ source.getAbsolutePath());
					}

					Log.i(TAG, "do copy now");

					try {
						/*
						 * if(mCutType){ cut(source, mDestDir); // mCutType =
						 * false; }else{
						 */
						
						boolean copied = copy(source, mDestDir);
						Log.i(TAG, "copied is " + String.valueOf(copied));
						if (copied && mCutType)
							if (source.exists())
								delete(source);						
						// }
					} catch (Exception e) {
						e.printStackTrace();
						Message msg = mEH.obtainMessage(COPY_NOSPACE_MSG, 0, 0,
								"");
						mEH.sendMessage(msg);
						mResume = false;
						while (mResume == false) {
							try {
								join(100);
								Log.d(TAG,"MyCopyOrCutThread catch exception e");
							} catch (InterruptedException e1) {
								// TODO Auto-generated catch block
								e1.printStackTrace();
							}
						}
						break;
					}
				}

				Log.d(TAG, "MyCopyOrCutThread exit stop state : *"
								+ mStop + ", count: " + mSrcFileList.size());
				mWakeLock.release();
				mProgressDialog.dismiss();
				backAfterPaste();

				Log.d(TAG, "copied files count : " + mDestDir.listFiles().length);

				if (mNeedBroadCastFileChanged) {
					Log.d(TAG, "to send file changed broadcast: "
							+ mDestDir.getAbsolutePath());
					sendBroadcast(new Intent(
							Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri
									.fromFile(mDestDir)));
					Log.d(TAG, "[notify mediascanner] copy file");
					FileUtil.notifyMediaScanner(mContext, null);	
					if (mCutType) {
						// Log.d("wuqf",
						// "*******to send file changed broadcast: " +
						// mSrcFileList.get(0).getParentFile().getAbsolutePath());
						sendBroadcast(new Intent(
								Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(mSrcFileList.get(0)
												.getParentFile())));
					}
					mNeedBroadCastFileChanged = false;
				}

				mCutType = false;
			}
		}

	}
	
	private void initMimeTypes() {
    	if(mMimeTypes == null){
   	   MimeTypeParser mtp = new MimeTypeParser();

//   	   XmlResourceParser in = getResources().getXml(com.android.internal.R.xml.mimetypes);
   	   XmlResourceParser in = getResources().getXml(R.xml.mimetypes);

   	   try {
   		   mMimeTypes = mtp.fromXmlResource(in);
   	   } catch (XmlPullParserException e) {
   		   Log.e(TAG,"PreselectedChannelsActivity: XmlPullParserException",e);
   		   throw new RuntimeException("PreselectedChannelsActivity: XmlPullParserException");
   	   } catch (IOException e) {
   		   Log.e(TAG, "PreselectedChannelsActivity: IOException", e);
   		   throw new RuntimeException("PreselectedChannelsActivity: IOException");
   	        }
    	}
    }
	
	private boolean neadBroadCast(String sFileName){
		File file = new File(sFileName);
		if(file.isDirectory())
			return false;
		
		String sTemp = sFileName.toLowerCase();
		if(mMimeTypes == null)
			initMimeTypes();
		
		String type = mMimeTypes.getMimeType(sTemp);
		if(type != null){ 
			if(type.startsWith("image") || type.startsWith("audio") || type.startsWith("video")){
				return true;
			}
		}
		
		return false;
	}
	
	private void doAction() {
		Log.i(TAG, "==> doAction");
		List<File> source = new ArrayList<File>();
		String path = null;
		
		requestCode = bundle.getInt(FileOp.KEY_INT_FOP_CODE);
		
		// get data
		switch (requestCode) {
		case FileOp.FOP_CREATE_DIR: //FileUtil._CREATEDIR
			Log.i(TAG, "do create dir");
			if (bundle.getString(FileOp.KEY_STRING_DEST_DIR_PATH) != null 
					&& bundle.getString(FileOp.KEY_STRING_DEST_FILE_NAME) != null ){
				path = bundle.getString(FileOp.KEY_STRING_DEST_DIR_PATH) + 
					"/" + bundle.getString(FileOp.KEY_STRING_DEST_FILE_NAME);
			}			
			break;
		case FileOp.FOP_RENAME://FileUtil._RENAME
			if (bundle.getString(FileOp.KEY_STRING_SRC_DIR_PATH) != null 
					&& bundle.getString(FileOp.KEY_STRING_SRC_FILE_NAME) != null){
				path = bundle.getString(FileOp.KEY_STRING_SRC_DIR_PATH) + "/" 
				+ bundle.getString(FileOp.KEY_STRING_SRC_FILE_NAME);
			}
			break;
		case FileOp.FOP_DELETE://FileUtil._DELETE
			Log.i(TAG, "do delete");
			int srcFrom = bundle.getInt(FileOp.KEY_INT_SRC_FROM);
			Log.i(TAG, "the src from is " + String.valueOf(srcFrom));
			if (FileOp.SRC_FROM_BUNDLE == srcFrom){			
				File file = new File(bundle.getString(FileOp.KEY_STRING_SRC_FILE_PATH));
				if (file.exists())
					source.add(file);				
			}else if (FileOp.SRC_FROM_CLIP == srcFrom){
				Log.i(TAG, "src from clip");
				if ( mfcpSelected.hasValidData()
						&& mfcpSelected.getOperation()==FileClipBoard.OP_DELETE){
					List<File> files = mfcpSelected.getItemsInList();
					Log.i(TAG, "the size of list is " + files.size());
					source.addAll(mfcpSelected.getItemsInList());	
					Log.i(TAG, "the item number in clip is " + String.valueOf(source.size()));
				}
			}
			break;
		case FileOp.FOP_CREATE_FILE://FileUtil._CREATEFILE
			Log.i(TAG, "do create file");
			path =  bundle.getString(FileOp.KEY_STRING_DEST_DIR_PATH);
			break;
		case FileOp.FOP_CUT://FileUtil._CUT
		case FileOp.FOP_COPY://FileUtil._COPY
			Log.i(TAG, "==> do copy file");
			if (mfcpSelected.hasValidData()
					&& (mfcpSelected.getOperation() == FileClipBoard.OP_CUT || mfcpSelected
							.getOperation() == FileClipBoard.OP_COPY)) {
				path = bundle.getString(FileOp.KEY_STRING_DEST_DIR_PATH);
				source.addAll(mfcpSelected.getItemsInList());
			}
			break;
		default: 
			if (bundle.getSerializable("source_files") != null) {// add by PH
				// 091012
				source.addAll( (List<File>) bundle.getSerializable("source_files"));
				path = source.get(0).getAbsolutePath();
			}			
			break;
		}
		
		
//		if (FileUtil._CREATEDIR == requestCode) {
//			if (bundle.getString("parent path") != null 
//					&& bundle.getString("file name") != null ){
//				path = bundle.getString("parent path") + "/" + bundle.getString("file name");
//			}
//		} else if (FileUtil._RENAME == requestCode) {
//			if (bundle.getString("parent path") != null 
//					&& bundle.getString("oldName") != null){
//				path = bundle.getString("parent path") + "/" + bundle.getString("oldName");
//			}
//		} else if (FileUtil._DELETE == requestCode) {
//			int srcFrom = bundle.getInt("srcfrom");
//			if (FileUtil.FROM_PATH == srcFrom){			
//				source = new ArrayList<File>();
//				File file = new File(bundle.getString("path"));
//				if (file.exists())
//					source.add(file);				
//			}else if (FileUtil.FROM_CLIP == srcFrom){
//				if ( mfcpSelected.hasValidData()
//						&& mfcpSelected.getOperation()==FileClipBoard.OP_DELETE){
//					source = mfcpSelected.getItemsInList();				
//				}
//			}
//		} else if(FileUtil._CREATEFILE == requestCode){
//			   path =  bundle.getString("parent path");
//		} else if (FileUtil._CUT == requestCode
//				|| FileUtil._COPY == requestCode) {
//			if (mfcpSelected.hasValidData()
//					&& (mfcpSelected.getOperation() == FileClipBoard.OP_CUT || mfcpSelected
//							.getOperation() == FileClipBoard.OP_COPY)) {
//				path = bundle.getString("destination");
//				source = mfcpSelected.getItemsInList();
//			}
//		} else {
//			if (bundle.getSerializable("source_files") != null) {// add by PH
//																	// 091012
//				source = (List<File>) bundle.getSerializable("source_files");
//				path = source.get(0).getAbsolutePath();
//			}
//		}
		
		
		// do action
		String status = Environment.getExternalStorageState();
		if (path != null && path.startsWith(FileUtil.sdroot) 
				|| status.equals(Environment.MEDIA_MOUNTED) 
				|| status.equals(Environment.MEDIA_MOUNTED_READ_ONLY)) {
			
			switch (requestCode) {
			case FileOp.FOP_COPY:	//FileUtil._COPY				
					copyInThread(source, new File(path));	
					break;
			case FileOp.FOP_CREATE_DIR:   //FileUtil._CREATEDIR
				if (bundle.getString(FileOp.KEY_STRING_DEST_FILE_NAME) == null) {
					wrong2browser();
				} else {
					if (createDir(path))
						backAfterCreate(path);
					else
						wrong2browser();
				}
				break;
			case FileOp.FOP_CREATE_FILE:  //FileUtil._CREATEFILE
				try {
					int type = 0;
					String name = bundle.getString(FileOp.KEY_STRING_DEST_FILE_NAME);
					if (name.endsWith(".doc"))
						type = 0;
					else if (name.endsWith(".xls"))
						type = 2;
					else if (name.endsWith(".ppt"))
						type = 1;
					else{
						Log.e(TAG, "unknown file type");
					}
					
//						if (createOffice(new File(bundle.getString("parent path"))))
					String fullPath = bundle.getString(FileOp.KEY_STRING_DEST_DIR_PATH) + "/" 
					+ bundle.getString(FileOp.KEY_STRING_DEST_FILE_NAME);
					if (createOffice(new File(fullPath), type))
						backAfterCreate(fullPath);
						else
							wrong2browser();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				break;
			case FileOp.FOP_DELETE:  //FileUtil._DELETE
				if (null != source) {
					Log.i(TAG, "item number is " + String.valueOf(source.size()));
					deleteInThread(source); //[improve] ArrayList / List
				}
				else
					Log.d(TAG, "source is null");
				break;
			case FileOp.FOP_CUT:  //FileUtil._CUT
				Log.i(TAG, "==> cutFile");
				//add by xieqm 110418
				for(int i=0;i<source.size();i++){
					Log.d(TAG, "the cut file is ============== " + source.get(i).getAbsolutePath());
				}
				//end
				cutInThread(source, new File(bundle.getString(FileOp.KEY_STRING_DEST_DIR_PATH)));
				break;
			case FileOp.FOP_RENAME:   //FileUtil._RENAME
				if (rename(bundle.getString(FileOp.KEY_STRING_SRC_DIR_PATH), 
						bundle.getString(FileOp.KEY_STRING_SRC_FILE_NAME), 
						bundle.getString(FileOp.KEY_STRING_DEST_DIR_PATH)))
					ok2browser();
				else
					wrong2browser();
				break;
			default:
				break;
			}
		} else {
			new AlertDialog.Builder(FileMan.this)
				.setTitle(R.string.remind).setMessage(
						R.string.sdunavailable).setPositiveButton(
							R.string.alert_dialog_ok,
							new DialogInterface.OnClickListener() {
								public void onClick(DialogInterface dialog,
										int whichButton) {
									FileMan.this.finish();
								}}).show();
		}
	}

	private class MyEventHandler extends Handler{
		public MyEventHandler(Looper looper){
			super(looper);
		}
		
		@Override
		public void handleMessage(Message msg){
			if(msg.what == COPY_ONSAME_MSG){//
				new AlertDialog.Builder(FileMan.this)
	            //.setIcon(R.drawable.alert_dialog_icon)
	            .setTitle(R.string.remind)
	            .setMessage(msg.obj.toString()+"\n"+getResources().getString(R.string.samefileexist))
	            .setPositiveButton(R.string.alert_dialog_on_samefile_yes, new DialogInterface.OnClickListener() {
	                public void onClick(DialogInterface dialog, int whichButton) {
	                	mCopyCutThread.mReplace = true;
	                	mCopyCutThread.toResume();
	                	flag = 1;
	                }
	            }).setNeutralButton(R.string.alert_dialog_on_samefile_no, new DialogInterface.OnClickListener(){
            	    public void onClick(DialogInterface dialog, int whichButton) {
            	    	mCopyCutThread.mReplace = false;
	                	mCopyCutThread.toResume();
	                	flag = 2;
	                }
	            }).setNegativeButton(R.string.alert_dialog_on_samefile_abort, new DialogInterface.OnClickListener() {
	                public void onClick(DialogInterface dialog, int whichButton) {
	                	mCopyCutThread.toStop();
	                	flag = 3;
	                }
			   }).show().setOnDismissListener(new OnDismissListener(){

                   public void onDismiss(DialogInterface dialog) {
	                  // TODO Auto-generated method stub
                	 //  Log.i(TAG, "555555555555555555555 flag = "+flag);
                	   if(flag == 1 || flag == 2 || flag == 3){

                	   }else{
                		   mCopyCutThread.toStop();
                		   mProgressDialog.dismiss();
                	   		}
                	   flag = 0;
                   }
                 }); 
			}else if(msg.what == COPY_NOSPACE_MSG){//
				new AlertDialog.Builder(FileMan.this)
				// .setIcon(R.drawable.alert_dialog_icon)
						.setTitle(R.string.remind).setMessage(
								R.string.nospaceonsd).setPositiveButton(
								R.string.alert_dialog_ok,
								new DialogInterface.OnClickListener() {
									public void onClick(DialogInterface dialog,
											int whichButton) {
										mCopyCutThread.toStop();
										mProgressDialog.dismiss();
									}
								}).show().setOnDismissListener(new OnDismissListener(){

				                      public void onDismiss(DialogInterface dialog) {
					                  // TODO Auto-generated method stub
				                    	  mCopyCutThread.toStop();
				                    	  mProgressDialog.dismiss();
				                      }
			                    });
				
			}else if (msg.what == DEST_INVALID) {
				new AlertDialog.Builder(FileMan.this)
				// .setIcon(R.drawable.alert_dialog_icon)
						.setTitle(R.string.remind)
						.setMessage(msg.obj.toString()+"\n"+getResources().getString(R.string.dest_nonexistent))
						.setPositiveButton(R.string.alert_dialog_ok,
								new DialogInterface.OnClickListener() {
									public void onClick(DialogInterface dialog,
											int whichButton) {
										mCopyCutThread.toStop();
										mProgressDialog.dismiss();
									}
								})
						.show()
						.setOnDismissListener(new OnDismissListener(){
									public void onDismiss(DialogInterface dialog) {
										// TODO Auto-generated method stub
										mCopyCutThread.toStop();
										mProgressDialog.dismiss();
									}
			                    });				
			}else if (msg.what == SRC_INVALID) {
				flag = 0;
				new AlertDialog.Builder(FileMan.this)
						.setTitle(R.string.remind)
						.setMessage(msg.obj.toString()+"\n"+getResources().getString(R.string.src_nonexistent))
						.setPositiveButton(R.string.src_nonexistent_skip,
								new DialogInterface.OnClickListener() {
									public void onClick(DialogInterface dialog,int whichButton) {
					                	mCopyCutThread.mbSkip = true;
					                	mCopyCutThread.mbSkipAll = false;
					                	mCopyCutThread.mbCancel = false;
					                	mCopyCutThread.toResume();
					                	flag = 1;
									}
						}).setNeutralButton(R.string.src_nonexistent_skip_all, 
								new DialogInterface.OnClickListener(){
		            	    public void onClick(DialogInterface dialog, int whichButton) {
			                	mCopyCutThread.mbSkip = false;
			                	mCopyCutThread.mbSkipAll = true;
			                	mCopyCutThread.mbCancel = false;
            	    			mCopyCutThread.toResume();
            	    					flag = 2;
            	    		}
						}).setNegativeButton(R.string.src_nonexistent_cancel, 
								new DialogInterface.OnClickListener(){
									public void onClick(DialogInterface dialog,int whichButton) {
					                	mCopyCutThread.mbSkip = false;
					                	mCopyCutThread.mbSkipAll = false;
					                	mCopyCutThread.mbCancel = true;
					                	mCopyCutThread.toResume();
											flag = 3;
									}
						}).show().setOnDismissListener(new OnDismissListener(){
				               public void onDismiss(DialogInterface dialog) {
				            	  // Log.i(TAG, "666666666666666666666 flag = "+flag);
				            	   if(flag == 1 || flag == 2 || flag == 3){

				            	   }else{
				            		   mCopyCutThread.toStop();
				            		   mProgressDialog.dismiss();
				            	   		}
				            	   flag = 0;
				                    }
			            });				
				
			}else if(msg.what == COPY_ONSAMEDIR_MSG){//
				flag = 0;
				new AlertDialog.Builder(FileMan.this)
						.setTitle(R.string.remind)
						.setMessage(msg.obj.toString()+"\n"+getResources().getString(R.string.dir_exist))
						.setPositiveButton(R.string.alert_dialog_on_samefile_yes,new DialogInterface.OnClickListener() {
									public void onClick(DialogInterface dialog,int whichButton) {
					                	mCopyCutThread.mReplaceDir = true;
					                	mCopyCutThread.toResume();
					                	flag = 1;
									}
						})
						.setNeutralButton(R.string.alert_dialog_on_samefile_no, new DialogInterface.OnClickListener(){
		            	    public void onClick(DialogInterface dialog, int whichButton) {
            	    			mCopyCutThread.mReplaceDir = false;
            	    			mCopyCutThread.toResume();
            	    					flag = 2;
            	    		}
						})
						.setNegativeButton(R.string.alert_dialog_on_samefile_abort, new DialogInterface.OnClickListener(){
									public void onClick(DialogInterface dialog,int whichButton) {
											mCopyCutThread.toStop();
											flag = 3;
									}
						}).show().setOnDismissListener(new OnDismissListener(){
				               public void onDismiss(DialogInterface dialog) {
				            	  // Log.i(TAG, "666666666666666666666 flag = "+flag);
				            	   if(flag == 1 || flag == 2 || flag == 3){

				            	   }else{
				            		   mCopyCutThread.toStop();
				            		   mProgressDialog.dismiss();
				            	   		}
				            	   flag = 0;
				                    }
			            });
			}else if (msg.what == COPY_ONSAMEDIR_MSG_ONLY_ONE){//
				flag = 0;
				new AlertDialog.Builder(FileMan.this)
						.setTitle(R.string.remind)
						.setMessage(msg.obj.toString()+"\n"+getResources().getString(R.string.dir_exist))
						.setPositiveButton(R.string.alert_dialog_on_samefile_yes,new DialogInterface.OnClickListener() {
									public void onClick(DialogInterface dialog,int whichButton) {
					                	mCopyCutThread.mReplaceDir = true;
					                	mCopyCutThread.toResume();
					                	flag = 1;
									}
						})
						.setNegativeButton(R.string.alert_dialog_on_samefile_abort, new DialogInterface.OnClickListener(){
									public void onClick(DialogInterface dialog,int whichButton) {
											mCopyCutThread.toStop();
											flag = 3;
									}
						}).show().setOnDismissListener(new OnDismissListener(){
				               public void onDismiss(DialogInterface dialog) {
				            	  // Log.i(TAG, "666666666666666666666 flag = "+flag);
				            	   if(flag == 1 || flag == 2 || flag == 3){

				            	   }else{
				            		   mCopyCutThread.toStop();
				            		   mProgressDialog.dismiss();
				            	   		}
				            	   flag = 0;
				                    }
			            });
			}
		}
	}
	
	public static int getFileCount(File file){
		int nFileCount = 0;
		if(file.isDirectory()){
			File [] files = file.listFiles();
			//if the directory is empty, delete it directly.
			if(files.length > 0){
				//if the directory is not empty,empty it before delete.
				int i;
				for (i=0; i<files.length; i++) {
					nFileCount += getFileCount(files[i]);
	       	 	}
			}
			
			return nFileCount;
		}else{
			return 1;
		}
	}

	public static  int getFileCount(final List<File> fileList){
		int nFileCount = 0;
		for(int i=0; i<fileList.size(); i++){
			nFileCount += getFileCount(fileList.get(i));
		}
		
		return nFileCount;
	}
	
	
	/*copy files to a directory
	 * @param fileList - a list contains source files
	 * @param dest -destination directory
	 */
	public void copyInThread(final List<File> fileList, final File dest) {
		Log.i(TAG, "==> copyInThread");
		
		if (fileList.isEmpty()) {
			wrong2browser();
		}
		
		int nTotalFileCount = getFileCount(fileList);
		if (nTotalFileCount <= 1) {
			// mProgressDialog.setIcon(R.drawable.alert_dialog_icon);
			mProgressDialog.setTitle(R.string.copy_progress);
			mProgressDialog.setMessage(getString(R.string.waiting));
			mProgressDialog.setCancelable(false);
			// mProgressDialog.setDefaultButton(false);
			mProgressDialog.setButton(getText(R.string.alert_dialog_cancel),new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog,int whichButton) {
							// User clicked No so do some stuff
							if (mCopyCutThread != null)
								mCopyCutThread.toStop();
							mCopyCutThread = null;
							finish();
						}
					});
			mProgressDialog.show();
		} else {
			// mProgressDialog.setIcon(R.drawable.alert_dialog_icon);
			mProgressDialog.setTitle(R.string.copy_progress);
			mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
			mProgressDialog.setMax(nTotalFileCount);
			mProgressDialog.setCancelable(true);
			mProgressDialog.setButton(getText(R.string.alert_dialog_cancel),new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog,int whichButton) {
							// User clicked No so do some stuff
							if (mCopyCutThread != null)
								mCopyCutThread.toStop();
							mCopyCutThread = null;
							finish();
						}
					});
			mProgressDialog.show();
		}
		
		mCopyCutThread = new CopyOrCutThread(this);
		mCopyCutThread.mDestDir = dest;
		mCopyCutThread.mSrcFileList = fileList;
		mCopyCutThread.start();			
		
	}
	
	private void cutInThread(final List<File> fileList, final File dest) {
		if (fileList.isEmpty()) {
			wrong2browser();
			finish();
			return;
		}
		if (fileList.get(0).getParent().equals(dest.getAbsolutePath())) {
			ok2browser();
			finish();
			return;
		}
		if (!dest.isDirectory() || !dest.exists()) {
			wrong2browser();
			finish();
			return;
		}
		String sParentPath = dest.getAbsolutePath();
		if (!sParentPath.endsWith("/")) {
			sParentPath += "/";
		}
		int nTotalFileCount = getFileCount(fileList);
		if (nTotalFileCount <= 1) {
			mProgressDialog.setTitle(R.string.cut_progress);
			mProgressDialog.setMessage(getString(R.string.waiting));
			mProgressDialog.setCancelable(false);
			// mProgressDialog.setDefaultButton(false);
			mProgressDialog.setButton(getText(R.string.alert_dialog_cancel),new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog,int whichButton) {
							// User clicked No so do some stuff
							if (mCopyCutThread != null)
								mCopyCutThread.toStop();
							mCopyCutThread = null;
							finish();
						}
					});
			mProgressDialog.show();
		} else {
			// mProgressDialog.setIcon(R.drawable.alert_dialog_icon);
			mProgressDialog.setTitle(R.string.cut_progress);
			mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
			mProgressDialog.setMax(nTotalFileCount);
			mProgressDialog.setCancelable(true);
			mProgressDialog.setButton(getText(R.string.alert_dialog_cancel),new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog,int whichButton) {
							// User clicked No so do some stuff
							if (mCopyCutThread != null)
								mCopyCutThread.toStop();
							mCopyCutThread = null;
							finish();
						}
					});
			mProgressDialog.show();
		}
		mNeedBroadCastFileChanged = false;
		mCopyCutThread = new CopyOrCutThread(this);
		mCopyCutThread.mDestDir = dest;
		mCopyCutThread.mSrcFileList = fileList;
		mCutType = true;
		
		mCopyCutThread.mbCancel = false;
		mCopyCutThread.mbSkip = false;
		mCopyCutThread.mbSkipAll = false;
		mCopyCutThread.start();
	}

	
	/* 
	 * Delete a file or directory. If the directory is not empty, clear it before delete.
	 * @param file - the file/directory to be deleted
	 */
	
	
	public void deleteInThread(final List<File> delFiles){
		final int nTotalFileCount = getFileCount(delFiles);
		
		Log.i(TAG, " nTotalFileCount = "+nTotalFileCount);
		
		if (nTotalFileCount <= 1) {
			mProgressDialog.setTitle(R.string.delete_file);
			mProgressDialog.setMessage(getString(R.string.waiting_deleting));
			mProgressDialog.setCancelable(false);
			// mProgressDialog.setDefaultButton(false);
			mProgressDialog.show();
			mDeleteThread = new DeleteThread(this) {
				public void run() {

					// [improve]
					// parent is used to broadcast msg to media scaner
					File parent = delFiles.get(0).getParentFile();
					for (File file : delFiles) {
						if (!file.exists())
							break;
						mDeleteThread.delete(file);

						// remove the file in clip
						FileMan.this.mfcpSelected.removeFile(file);
					}
					mProgressDialog.dismiss();
					mProgressDialog = null;
					ok2browser();
					if (mNeedBroadCastFileChanged) {
						if (1 == delFiles.size() && delFiles.get(0).isFile()){
							Log.d(TAG, "[notify media-scanner] delete one file : "
									+ delFiles.get(0).getAbsolutePath());
							FileUtil.notifyMediaScanner(mContext, delFiles.get(0));
						}
						mNeedBroadCastFileChanged = false;
					}
				}
			};
			mDeleteThread.start();
		} else {
//	        mProgressDialog.setIcon(R.drawable.alert_dialog_icon);
           mProgressDialog.setTitle(R.string.delete_progress);//modified by PH 091015
           mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
           mProgressDialog.setMax(nTotalFileCount);
           mProgressDialog.setCancelable(true);
           mProgressDialog.setButton(getText(R.string.alert_dialog_cancel), new DialogInterface.OnClickListener() {
               public void onClick(DialogInterface dialog, int whichButton) {
               // User clicked No so do some stuff            	   
          	      if(mDeleteThread != null)
          	    	  		mDeleteThread.toStop();
          	      		mDeleteThread = null;   
          	      finish();
                    }
              });
           mProgressDialog.show();
		
           mDeleteThread = new DeleteThread(this){
		         public void run(){
						mWakeLock.acquire();						
			          for(File file : delFiles)	{
				           if(mStop || !file.exists())//add by wqf 091022
					            break;
				       //    Log.i(TAG, "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ delete break $$$$$$$$$$$$$$$$$$$$$$$$$");
				           mDeleteThread.delete(file);	
				           
							// remove the file in clip
							FileMan.this.mfcpSelected.removeFile(file);
		  	              }		
			       //   Log.i(TAG, "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ delete break $$$$$$$$$$$$$$$$$$$$$$$$$");
		             mProgressDialog.dismiss();
		             mProgressDialog = null;
				       ok2browser();
				   
					if (mNeedBroadCastFileChanged) {
						Log.d(TAG, "[notify media-scanner] delete many files");
						FileUtil.notifyMediaScanner(mContext, null);
						mNeedBroadCastFileChanged = false;
					}			       
						mWakeLock.release();
			       }		   
		     };
		    mDeleteThread.start();		
	    }
	}
	//create a new file under an directory with the name
	//Dest: the Destination directory
	//name: file's name
	public boolean createFile(File Dest, String filename){
		if (!Dest.isDirectory()){
			Toast.makeText(FileMan.this, R.string.notadirectory, Toast.LENGTH_SHORT).show();
			return false;
		}else{
			File file = new File(Dest + "/" + filename);
			if(!file.exists())
				try{
					return file.createNewFile();
				}catch (IOException e){
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		}
		return false;		
	}
	
	/*	create a new directory according to a path
	 *	@path: the directory's path
	 *	return: true - create successfully
	 *       false - the directory exists
	 * 
	 */
	public boolean createDir(String path){
		Log.i(TAG, "==> createDir");
		
		File dir = new File(path);
		
		if(dir.exists() && dir.isDirectory()){
			Log.e(TAG, "the new folder is existent");
			return false;
		}else {
			if(dir.mkdir()){
				Toast.makeText(this, R.string.tst_newfolder_msg_ok, 3).show();
			}else{
				Toast.makeText(this, R.string.tst_newfolder_msg_fail, 3).show();
			}			
			return dir.exists();			
		}	
	}

	//[improve] 
	public boolean createOffice(File path, int type) throws IOException{
		boolean ret;
	
		File file = null;
		byte[] data = null;
		switch(type){
		case 0:
		{
			file = new File(path.getAbsolutePath());
			   InputStream in = getResources().openRawResource(R.raw.tempword);
			   BufferedInputStream bi = new BufferedInputStream(in);
			   FileOutputStream  fo = new FileOutputStream(file);
			   BufferedOutputStream bo = new BufferedOutputStream(fo);
			  data = new byte[in.available()];
			   Log.d(TAG, "********file len : " + in.available());
			   while(bi.read(data) != -1){
				   bo.write(data);
			   }
			   bo.flush();
			   bi.close();
			   bo.close();
			   Toast.makeText(FileMan.this, R.string.tst_newfile_msg_ok, Toast.LENGTH_SHORT).show();
		}
			break;
		case 1:
		{
			file = new File(path.getAbsolutePath());
			   InputStream in = getResources().openRawResource(R.raw.temppowerpoint);
			   BufferedInputStream bi = new BufferedInputStream(in);
			   FileOutputStream  fo = new FileOutputStream(file);
			   BufferedOutputStream bo = new BufferedOutputStream(fo);
			   data = new byte[in.available()];
			   Log.d(TAG, "********file len : " + in.available());
			   while(bi.read(data) != -1){
				   bo.write(data);
			   }
			   bo.flush();
			   bi.close();
			   bo.close();
			   Toast.makeText(FileMan.this, R.string.tst_newfile_msg_ok, Toast.LENGTH_SHORT).show();
		}
			break;
		case 2:
		{
			file = new File(path.getAbsolutePath());
			   InputStream in = getResources().openRawResource(R.raw.tempexcel);
			   BufferedInputStream bi = new BufferedInputStream(in);
			   FileOutputStream  fo = new FileOutputStream(file);
			   BufferedOutputStream bo = new BufferedOutputStream(fo);
			   data = new byte[in.available()];
			   Log.d(TAG, "********file len : " + in.available());
			   while(bi.read(data) != -1){
				   bo.write(data);
			   }
			   bo.flush();
			   bi.close();
			   bo.close();
			   Toast.makeText(FileMan.this, R.string.tst_newfile_msg_ok, Toast.LENGTH_SHORT).show();
		}
			break;
		default:
			break;				
		}   			
			return true;
		}
	
	public boolean rename(String path, String oldname, String newname) {
		Log.i(TAG, "==> rename");
		
		boolean ret = false;
		
		if (!oldname.equals(newname)) {

			File oldfile = new File(path + "/" + oldname);
			File newfile = new File(path + "/" + newname);

			mfcpSelected.removeFile(oldfile);
			
			ret = oldfile.renameTo(newfile);
			if (ret) {				
				// remove the old file in clip, if it is in clip 
				if(oldfile.exists()){
					Log.i(TAG, "the old file existed");
				}
				
				Toast.makeText(this, R.string.tst_rename_change_ok, 3).show(); 

				if (newfile.isDirectory()) {
					// [improve]
					Log.d(TAG, "to broadcast : "+ oldfile.getAbsolutePath());
//					sendBroadcast(new Intent(
//							Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri
//									.fromFile(oldfile)));
//
//					Log.d(TAG, "to broadcast : "+ newfile.getAbsolutePath());
//					sendBroadcast(new Intent(
//							Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri
//									.fromFile(newfile)));
					FileUtil.notifyMediaScanner(this, null);
				} else {
					
					// [improve]comment below code for a strange issue
					// after rename an image file, the old file still is there
					if (neadBroadCast(oldname)) {
						Log.d(TAG, "[notify mediascanner] rename one file : old name is " + oldfile.getAbsolutePath());
						FileUtil.notifyMediaScanner(this, oldfile);	
					}
					
					if (neadBroadCast(newname)) {
						Log.d(TAG, "[notify mediascanner] rename one file : new name is " + newfile.getAbsolutePath());
						FileUtil.notifyMediaScanner(this, newfile);
					}
				}

			} else {
				mfcpSelected.addFile(oldfile);
				Toast.makeText(this, R.string.rename_file_fail, 3).show();
			}
		}

		return ret;
	}
	
	private void backAfterCreate(String path) {
		
		if (null != intent) {
			intent.putExtra("NEW_FILE", path);
			setResult(RESULT_OK, intent);
		}
		finish();
	}
	
	private void backAfterPaste() {
		
		if (null != intent) {
			if (null != mlNewFiles && mlNewFiles.size() > 0){
				Log.i(TAG, "the new file size is " + mlNewFiles.size());
				intent.putStringArrayListExtra("NEW_FILES", mlNewFiles);
			}
			setResult(RESULT_OK, intent);
		}
		finish();
	}

	private void ok2browser(){
		Log.i(TAG, "==> ok2browser");
		
		if(requestCode == FileOp.FOP_DELETE){
			intent.putExtras(bundle);
			setResult(RESULT_OK, intent);
		}
		
		if(requestCode == FileOp.FOP_RENAME){
			setResult(RESULT_OK, intent);
		}		
		
		finish();		
	}
	
	private void wrong2browser(){
		setResult(RESULT_CANCELED, intent);							
		finish();		
	}       	
	
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		switch (keyCode) {
		case KeyEvent.KEYCODE_BACK: {
			
			return true;
		}
		}
		return super.onKeyDown(keyCode, event);
	}
}
